home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Found / FWString / Sources / SLTxtPar.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  12.2 KB  |  372 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                SLTxtPar.cpp
  4. //    Release Version:    $ ODF 1  $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifndef SLTXTPAR_H
  13. #include "SLTxtPar.h"
  14. #endif
  15.  
  16. #ifndef SLPRIDEB_H
  17. #include "SLPriDeb.h"
  18. #endif
  19.  
  20. #ifndef SLPRIMEM_H
  21. #include "SLPriMem.h"
  22. #endif
  23.  
  24. #ifdef FW_BUILD_MAC
  25. #include <Script.h>
  26. #endif
  27.  
  28. #ifdef FW_BUILD_MAC
  29. #pragma segment Strings
  30. #endif
  31.  
  32. //========================================================================================
  33. //    struct FW_ODTradITextData
  34. //========================================================================================
  35.  
  36. struct FW_ODTradITextData
  37. {
  38.     FW_Locale    fLocale;
  39.     char        fText[1];        // Variable length array!
  40. };
  41.  
  42. //========================================================================================
  43. //    Parameter functions for Traditional Mac Text
  44. //========================================================================================
  45.  
  46. const size_t kTradMacTextOffset = sizeof(FW_Locale);
  47.  
  48. // We declare the following functions extern "C" even though they are static
  49. // (and therefore private to this module) because the FW_ODITextFunctions struct
  50. // expects an array of "C" functions.  A strict type checking compiler such as
  51. // SCpp will not allow you to do it otherwise. - (SFU)
  52.  
  53. extern "C"
  54. {
  55.     static void TradMac_GetODITextParams(ODIText* text, 
  56.                                         FW_ODITextParams* params,
  57.                                         FW_PlatformError* error);
  58.     static FW_Boolean TradMac_IsCharacterStart(ODIText* text, 
  59.                                         FW_BytePosition, 
  60.                                         FW_BytePosition,
  61.                                         FW_PlatformError* error);
  62.     static FW_BytePosition TradMac_GetBytePosition(ODIText* text, 
  63.                                         FW_CharacterPosition,
  64.                                         FW_PlatformError* error);
  65.     static void TradMac_SetCapacity(ODIText *text,
  66.                                     long capacity,
  67.                                     FW_Boolean deletePrevBuffer,
  68.                                     FW_PlatformError* error);
  69.     static void TradMac_SetLength(ODIText* text, 
  70.                                         long,
  71.                                         FW_PlatformError* error);
  72.     static void TradMac_SetLocale(ODIText* text, 
  73.                                         FW_Locale locale,
  74.                                         FW_PlatformError* error);
  75. }
  76.  
  77. //----------------------------------------------------------------------------------------
  78. // TradMac_GetODITextParams
  79. //----------------------------------------------------------------------------------------
  80.  
  81. static void TradMac_GetODITextParams(ODIText *text, 
  82.                                     FW_ODITextParams* params,
  83.                                     FW_PlatformError* error)
  84. {
  85.     *error = 0;
  86.     params->fTextStart = (char*) text->text._buffer + kTradMacTextOffset;
  87.     params->fTextByteLength = text->text._length - kTradMacTextOffset;
  88.     params->fTextByteCapacity = text->text._maximum - kTradMacTextOffset;
  89. #ifdef FW_BUILD_MAC
  90.     ODByteArray *array = &text->text;
  91.     FW_ODTradITextData *iTextData = (FW_ODTradITextData *) array->_buffer;
  92.     params->fTextLocale = iTextData->fLocale;
  93. #else
  94.     // This is a hack until OpenDoc for Windows does the right thing
  95.     params->fTextLocale.fScriptCode = 0;
  96.     params->fTextLocale.fLangCode = 0;
  97. #endif
  98. }
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // TradMac_IsCharacterStart
  102. //----------------------------------------------------------------------------------------
  103.  
  104. static FW_Boolean TradMac_IsCharacterStart(ODIText *text,                                             
  105.                                     FW_BytePosition knownCharacterStartPosition, 
  106.                                     FW_BytePosition positionToCheck,
  107.                                         FW_PlatformError* error)
  108. {
  109.     FW_Boolean result = true;    // assume true, which will be the case for single-byte scripts
  110.     *error = 0;
  111.  
  112. #ifdef FW_BUILD_MAC
  113.     //KVV For Windows, always assume single-byte character set
  114.     ODByteArray *array = &text->text;
  115.     FW_ODTradITextData *data = (FW_ODTradITextData *) array->_buffer;
  116.     
  117.     if (!::FW_LocaleIsSingleByte(data->fLocale))
  118.     {
  119.         // return true if byte is first byte of a character
  120.         // This doesn't make a distinction between single-byte and double-byte characters
  121.         result = ::CharacterByteType(data->fText+knownCharacterStartPosition, 
  122.                         positionToCheck-knownCharacterStartPosition, 
  123.                         data->fLocale.fScriptCode) != smLastByte;
  124.     }
  125. #endif
  126.  
  127.     return result;
  128. }
  129.  
  130. //----------------------------------------------------------------------------------------
  131. // TradMac_GetBytePosition
  132. //----------------------------------------------------------------------------------------
  133.  
  134. static FW_BytePosition TradMac_GetBytePosition(ODIText *text, FW_CharacterPosition position,
  135.                                         FW_PlatformError* error)
  136. {
  137.     FW_BytePosition result = position;    // assume single byte characters
  138.     *error = 0;
  139.     
  140.     ODByteArray *array = &text->text;
  141.     FW_ODTradITextData *data = (FW_ODTradITextData *) array->_buffer;
  142.  
  143. #ifdef FW_BUILD_MAC
  144.     //KVV For Windows, always assume single-byte character set
  145.     if (!::FW_LocaleIsSingleByte(data->fLocale))
  146.     {
  147.         char* p = data->fText;
  148.         char* lastCharStart = p;
  149.         result = 0;
  150.         while (position > 0)
  151.         {
  152.             if (smLastByte != ::CharacterByteType(p, p - lastCharStart, data->fLocale.fScriptCode))
  153.             {
  154.                 ++result;
  155.                 lastCharStart = p;
  156.             }
  157.             ++p;
  158.             --position;
  159.         }
  160.     }
  161. #endif
  162.  
  163.     return result;
  164. }
  165.  
  166. //----------------------------------------------------------------------------------------
  167. // TradMac_SetCapacity
  168. //----------------------------------------------------------------------------------------
  169.  
  170. static void TradMac_SetCapacity(ODIText *text,
  171.                                     long capacity,
  172.                                     FW_Boolean deletePrevBuffer,
  173.                                     FW_PlatformError* error)
  174. {
  175.     FW_ERR_TRY
  176.     {
  177.         if (capacity > long(text->text._maximum - kTradMacTextOffset))
  178.         {
  179.             unsigned char *newBuffer = new unsigned char[capacity+kTradMacTextOffset];
  180.             ::FW_PrimitiveCopyMemory(text->text._buffer, newBuffer, text->text._length);
  181.             if (deletePrevBuffer)
  182.                 delete [] text->text._buffer;
  183.             text->text._buffer = newBuffer;
  184.             text->text._maximum = capacity+kTradMacTextOffset;
  185.         }
  186.     }
  187.     FW_ERR_CATCH
  188. }
  189.  
  190. //----------------------------------------------------------------------------------------
  191. // TradMac_SetLength
  192. //----------------------------------------------------------------------------------------
  193.  
  194. static void TradMac_SetLength(ODIText *text, long length,
  195.                                         FW_PlatformError* error)
  196. {
  197.     *error = 0;
  198.     FW_PRIV_ASSERT(length <= long(text->text._maximum - kTradMacTextOffset));
  199.     text->text._length = length + kTradMacTextOffset;
  200. }
  201.  
  202. //----------------------------------------------------------------------------------------
  203. // TradMac_SetLocale
  204. //----------------------------------------------------------------------------------------
  205.  
  206. static void TradMac_SetLocale(ODIText *text, FW_Locale locale, FW_PlatformError* error)
  207. {
  208.     *error = 0;
  209.     ODByteArray *array = &text->text;
  210.     FW_ODTradITextData *iTextData = (FW_ODTradITextData *) array->_buffer;
  211.     iTextData->fLocale = locale;    
  212. }
  213.  
  214. //----------------------------------------------------------------------------------------
  215. // gTraditionalMacFunctions
  216. //----------------------------------------------------------------------------------------
  217.  
  218. FW_ODITextFunctions gTraditionalMacFunctions = 
  219. {
  220.     TradMac_GetODITextParams,
  221.     TradMac_IsCharacterStart,
  222.     TradMac_GetBytePosition,
  223.     TradMac_SetCapacity,
  224.     TradMac_SetLength,
  225.     TradMac_SetLocale
  226. };
  227.  
  228. //========================================================================================
  229. //    Text Format Registry Functions
  230. //========================================================================================
  231.  
  232. struct PrivRegistryEntry
  233. {
  234.     ODITextFormat            fFormat;
  235.     FW_ODITextFunctions*    fFunctions;
  236. };
  237.  
  238. static PrivRegistryEntry gRegistryMap[] =
  239. {
  240.     { kODTraditionalMacText, &gTraditionalMacFunctions }
  241. };
  242.  
  243. const int kNumberFormats = sizeof(gRegistryMap) / sizeof(PrivRegistryEntry);
  244.  
  245. //----------------------------------------------------------------------------------------
  246. // PrivGetFormatFunctions
  247. //----------------------------------------------------------------------------------------
  248.  
  249. static FW_ODITextFunctions* PrivGetFormatFunctions(ODITextFormat format)
  250. {
  251.     // We cache the last format,functions pair used.
  252.     // This not only will speed up the usual case where we're continually
  253.     // just getting the FormatFunctions for the same ODIFormat (i.e. kODTraditionalMacText),
  254.     // it will usually save us from even needing to instantiate the PrivTextFormatMap.
  255.     // Any part that uses kODTraditionalMacText exclusively will never execute 
  256.     // PrivGetTextFormatMap, so it will never instantiate the map.
  257.     
  258.     static ODITextFormat gLastFormat = kODTraditionalMacText;
  259.     static FW_ODITextFunctions* gLastFunctions = &gTraditionalMacFunctions;
  260.     
  261.     FW_ODITextFunctions* result = 0;
  262.     if (format == gLastFormat)
  263.         result = gLastFunctions;
  264.     else
  265.     {
  266.         for (int i=0; i<kNumberFormats; i++)
  267.         {
  268.             if (gRegistryMap[i].fFormat == format)
  269.                 result = gRegistryMap[i].fFunctions;
  270.         }
  271.         if (result)
  272.         {
  273.             gLastFormat = format;
  274.             gLastFunctions = result;
  275.         }
  276.     }
  277.     return result;
  278. }
  279.  
  280. //========================================================================================
  281. //    ODIText Parameter Functions
  282. //========================================================================================
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // FW_TextParams_GetParams
  286. //----------------------------------------------------------------------------------------
  287.  
  288. void FW_TextParams_GetParams(ODIText *text, 
  289.                             FW_ODITextParams* params,
  290.                             FW_PlatformError* error)
  291. {
  292.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  293.     FW_PRIV_ASSERT(functions);
  294.     (functions->fGetParams)(text, params, error);
  295. }
  296.  
  297. //----------------------------------------------------------------------------------------
  298. // FW_TextParams_IsCharacterStart
  299. //----------------------------------------------------------------------------------------
  300.  
  301. FW_Boolean FW_TextParams_IsCharacterStart(ODIText *text,                                             
  302.                                     FW_BytePosition knownCharacterStartPosition, 
  303.                                     FW_BytePosition positionToCheck,
  304.                                     FW_PlatformError* error)
  305. {
  306.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  307.     FW_PRIV_ASSERT(functions);
  308.     return (functions->fIsCharacter)(text, knownCharacterStartPosition, positionToCheck, error);
  309. }
  310.  
  311. //----------------------------------------------------------------------------------------
  312. // FW_TextParams_GetBytePosition
  313. //----------------------------------------------------------------------------------------
  314.  
  315. FW_BytePosition FW_TextParams_GetBytePosition(ODIText *text,
  316.                                     FW_CharacterPosition position,
  317.                                     FW_PlatformError* error)
  318. {
  319.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  320.     FW_PRIV_ASSERT(functions);
  321.     return (functions->fGetBytePos)(text, position, error);
  322. }
  323.  
  324. //----------------------------------------------------------------------------------------
  325. // FW_TextParams_SetCapacity
  326. //----------------------------------------------------------------------------------------
  327.  
  328. void FW_TextParams_SetCapacity(ODIText *text, 
  329.                                 long capacity, 
  330.                                 FW_Boolean deletePrevBuffer,
  331.                                 FW_ODITextParams* params,
  332.                                 FW_PlatformError* error)
  333. {
  334.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  335.     FW_PRIV_ASSERT(functions);
  336.     (functions->fSetCapacity)(text, capacity, deletePrevBuffer, error);
  337.     if (!*error) 
  338.         (functions->fGetParams)(text, params, error);
  339. }
  340.  
  341. //----------------------------------------------------------------------------------------
  342. // FW_TextParams_SetLength
  343. //----------------------------------------------------------------------------------------
  344.  
  345. void FW_TextParams_SetLength(ODIText *text, 
  346.                                 long length, 
  347.                                 FW_ODITextParams* params,
  348.                                 FW_PlatformError* error)
  349. {
  350.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  351.     FW_PRIV_ASSERT(functions);
  352.     (functions->fSetLength)(text, length, error);
  353.     if (!*error) 
  354.         (functions->fGetParams)(text, params, error);
  355. }
  356.  
  357. //----------------------------------------------------------------------------------------
  358. // FW_TextParams_SetLength
  359. //----------------------------------------------------------------------------------------
  360.  
  361. void FW_TextParams_SetLocale(ODIText *text, 
  362.                                 FW_Locale locale,
  363.                                 FW_ODITextParams* params,
  364.                                 FW_PlatformError* error)
  365. {
  366.     FW_ODITextFunctions* functions = PrivGetFormatFunctions(text->format);
  367.     FW_PRIV_ASSERT(functions);
  368.     (functions->fSetLocale)(text, locale, error);
  369.     if (!*error) 
  370.         (functions->fGetParams)(text, params, error);
  371. }
  372.